/*
 * Copyright (C) 2011 flashflexpro@gmail.com  All Rights Reserved.  No
 *   use, copying or distribution of this work may be made except in
 *   accordance with a valid license agreement from flashflexpro@gmail.com
 *   This notice must be included on all copies, modifications and
 *   derivatives of this work.
 *
 *   flashflexpro@gmail.com MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT
 *   THE SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED,
 *   INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 *   NON-INFRINGEMENT. flashflexpro@gmail.com SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED
 *   BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS
 *   SOFTWARE OR ITS DERIVATIVES.
 */

package com.flashflexpro.as3lib {

	public class ModelToViewSyncer {

        public function ModelToViewSyncer(thisObj:Object, modelList:Object, viewList:Object) {
            _thisObj = thisObj;
            _modelList = modelList;
            _viewList = viewList;
        }

        protected var _thisObj:Object;

        public function get thisObj():Object {
            return _thisObj;
        }

        protected var _modelList:Object;
        public function get modelList():Object{
            return _modelList;
        }

        protected var _viewList:Object;


        public function get viewList():Object {
            return _viewList;
        }

        public function sync(
                modelListLength:int, getModelListElementAt:Function,
                getViewListLength:Function, getViewElementAt:Function, addViewListElement:Function, setViewListElementIndex:Function, removeViewElementAtIndex:Function,
                doesViewBelongsToThisModel:Function, newViewElementFromModelElement:Function ):void {

            /**
             * from the top of each dto
             */
            for (var modelIndex:int = 0; modelIndex < modelListLength; modelIndex ++) {
                var currentModelEle:Object = getModelListElementAt.apply( _thisObj, [ modelIndex ]);
                var currentViewEle:Object;
                var foundViewIndex:int = -1;
                //try to find existing dto from treeNode
                for (var viewIndex:int = modelIndex; viewIndex < getViewListLength.apply( _thisObj ); viewIndex ++) {
                    currentViewEle = getViewElementAt.apply( _thisObj, [ viewIndex ] );
                    if (doesViewBelongsToThisModel.apply( _thisObj, [ currentViewEle, currentModelEle ])) {
                        foundViewIndex = viewIndex;
                        break;
                    }
                }


                if (foundViewIndex == modelIndex) {
                    //great! right model, right position

                }
                else {
                    if (foundViewIndex < 0) {
                        currentViewEle = newViewElementFromModelElement.apply( _thisObj, [ currentModelEle ]);
                        addViewListElement.apply( _thisObj, [ currentViewEle ]);
                    }
                    else {
                        //wrong position
                    }
                    setViewListElementIndex.apply( _thisObj, [ currentViewEle, modelIndex ]);
                }
            }

            /**
             * get rid of the tree nodes whose dto are not in the dtos
             */
            while (getViewListLength.apply( viewList ) > modelListLength) {
                removeViewElementAtIndex.apply( _thisObj, [ modelListLength ] );
            }
        }

	}

}
